package strategies;

//~--- non-JDK imports --------------------------------------------------------

import com.dukascopy.api.IOrder;
import com.dukascopy.api.JFException;

//~--- JDK imports ------------------------------------------------------------

import java.util.Date;
import java.util.List;
import java.util.ListIterator;

public class LongTermStrategy extends Strategy {
    public LongTermStrategy(StrategyArgs args) {
        super(args);
        tradingZone = true;
    }

    protected void initStates() {
        super.initStates();
    }

    protected void initSarLines() {
        super.initSarLines();
    }

    protected void evaluateTradeEntry() throws JFException {
        SarLine uslLine = SarLine.sarMap.get(this).get("USL");
        SarLine lslLine = SarLine.sarMap.get(this).get("LSL");

        // LOok for LONG state...
        if ((state == States.READY_TOGO_SHORT) || (state == States.LOOK_FOR_SHORT) || (state == States.NEXT_ONLY_LONG)
                || (state == States.START)) {
            if (uslLine.isBreached(latestTick)) {
                state = States.LOOK_FOR_LONG;
                uslLine.resetExtremePoint(latestTick.getBid());

                // context.getConsole().getOut().println(state.toString());
            }
        }

        if (state == States.LOOK_FOR_LONG) {
            if (uslLine.getCandlesAfterEP() > arguments.getCandleThreshold()) {
                state = States.READY_TOGO_LONG;
                uslLine.setTradeEntryThreshold(uslLine.getExtremePoint());
            }
        }

        /*
         * if (state == States.LOOK_FOR_LONG) {
         *       if (lflLine.isBreached(latestTick)) {
         *               state = States.START;
         *       }
         * }
         */
        if (state == States.READY_TOGO_LONG) {
            if (latestTick.getBid() > (uslLine.getTradeEntryThreshold() + BREACH_THRESHOLD)) {
                buy(localInstrument);
            }
        }

        // SHORT
        if ((state == States.READY_TOGO_LONG) || (state == States.LOOK_FOR_LONG) || (state == States.NEXT_ONLY_SHORT)
                || (state == States.START)) {
            if (lslLine.isBreached(latestTick)) {
                state = States.LOOK_FOR_SHORT;
                lslLine.resetExtremePoint(latestTick.getBid());

                // context.getConsole().getOut().println(state.toString());
            }
        }

        if (state == States.LOOK_FOR_SHORT) {
            if (lslLine.getCandlesAfterEP() > arguments.getCandleThreshold()) {
                state = States.READY_TOGO_SHORT;
                lslLine.setTradeEntryThreshold(lslLine.getExtremePoint());
            }
        }

        /*
         * if (state == States.LOOK_FOR_SHORT) {
         *       if (uflLine.isBreached(latestTick)) {
         *               state = States.START;
         *       }
         * }
         */
        if (state == States.READY_TOGO_SHORT) {
            if (latestTick.getBid() < (lslLine.getTradeEntryThreshold() - BREACH_THRESHOLD)) {
                sell(localInstrument);
            }
        }
    }

    protected void evaluateTradeExit() throws JFException {
        if (positionsTotal(localInstrument) > 0) {
            SarLine uslLine                 = SarLine.sarMap.get(this).get("USL");
            SarLine lslLine                 = SarLine.sarMap.get(this).get("LSL");
            boolean useStopLoss             = (arguments.getStopLoss() > 0)
                                              ? true
                                              : false;
            boolean useTakeProfit           = (arguments.getTakeProfit() > 0)
                                              ? true
                                              : false;
            boolean isShort                 = (state == States.SHORT);
            boolean isLong                  = (state == States.LONG);
            double  longProfitOrLossInPips  = (latestTick.getBid() - orderOpenPrice) * 10000;
            double  shortProfitOrLossInPips = (orderOpenPrice - latestTick.getAsk()) * 10000;

            if ((isShort
                    && ((useTakeProfit && (shortProfitOrLossInPips >= arguments.getTakeProfit()))
                        || (uslLine.isBreached(latestTick))
                        || (useStopLoss && (-shortProfitOrLossInPips >= arguments.getStopLoss())))) || (isLong
                            && ((useTakeProfit && (longProfitOrLossInPips >= arguments.getTakeProfit()))
                                || (lslLine.isBreached(latestTick))
                                || (useStopLoss && (-longProfitOrLossInPips >= arguments.getStopLoss()))))) {

                // Cover any open positions...
                List<IOrder> orders = engine.getOrders(localInstrument);

                if (orders.size() > 1) {
                    context.getConsole().getOut().println("Error more than one pending order: " + orders.size());
                }

                ListIterator<IOrder> orderIter = orders.listIterator();

                while (orderIter.hasNext()) {
                    IOrder order = orderIter.next();

                    engine.closeOrders(order);
                    orderClosePrice = (state == States.SHORT)
                                      ? latestTick.getAsk()
                                      : latestTick.getBid();
                    orderCloseTime  = latestTick.getTime();

                    Date tempCloseTime = new Date(orderCloseTime);

                    daysProfit += (state == States.SHORT)
                                  ? (orderOpenPrice - orderClosePrice - BROKERAGE)
                                  : (orderClosePrice - orderOpenPrice - BROKERAGE);
                    context.getConsole().getOut().println(tempCloseTime.toGMTString() + ", COVER-" + state.toString()
                            + "," + account.getEquity());

                    int conseqTrades = (state == States.LONG)
                                       ? conseqLongs
                                       : conseqShorts;

                    if (conseqTrades >= arguments.getMaxConsecutivePositions()) {
                        state = (state == States.LONG)
                                ? States.NEXT_ONLY_SHORT
                                : States.NEXT_ONLY_LONG;
                    } else {
                        state = (state == States.LONG)
                                ? States.LOOK_FOR_LONG
                                : States.LOOK_FOR_SHORT;
                    }
                }
            }
        }
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
